<?php

include_once 'common.php';

define('CLIPS_PER_ROW',3);
define('CLIP_ROWS',3);

class CronJob {

  function CronJob() {

  }

  /**
   * The main juice.  Called to create all the sub images from the cron
   * job and the direct upload page.
   * @param $fullFile the full uploaded image
   * @param $sec sec obtained from calling datetime()
   * @param $description description of the image (body in emails)
   * @param $location location of the image (subject in emails)
   * @param $lat latitude (can be null)
   * @param $lng longitude (can be null)
   */
  function processImageFile($fullFile,$sec,$description,
                            $location,$lat=NULL,$lng=NULL) {
    
    $outdir = config('relative_path');
    note("Using outdir:" . $outdir);
    if (!preg_match('/.*\/$/',$outdir)) {
      $outdir .= '/';
    }
    
    $file = fullImageFileName($outdir,$sec);
    if ($file != $fullFile) {
      exec('cp ' . $fullFile . ' ' . $file);
    }
    
    $clipFile       = $outdir . $sec . "-clip.jpg";
    $outFile        = $outdir . $sec . ".jpg";
    $outDescription = $outdir . $sec . ".des";
    $outLocation    = $outdir . $sec . ".loc";
    $whoLocation    = $outdir . $sec . ".who";
     
    // Create images
    $this->writeSmallImage($fullFile,$outFile);
    $this->writeClipImage($outFile,$clipFile);
    
      // Write the meta data
    writeFile($outDescription, $description);
    writeFile($outLocation,    $location);
    writeFile($whoLocation,    $who);

    // Clean up
    if ($file != $fullFile) {
      exec('rm ' . $fullFile);
    }
  }
  
  /**
   * @param $outdir the output directory for images
   * @param $sec    the value from datetime(), needed later.
   */
  function fullImageFileName($outdir,$sec) {
    return $outdir . $sec . "-full.jpg";
  }
  
  /**
   * Writes a 75x75 clipped image.
   *
   * @param file input file
   * @param clipFile output file
   */
  function writeClipImage($file,$outFile) {
    $clipWidth  = 75;
    $clipHeight = 75;
    note('writing clip image');
    resizeImage($file,$outFile,$clipWidth,$clipHeight);
  }
  
  /**
   * Writes a smaller file.
   *
   * @param file input file
   * @param clipFile output file
   */
  function writeSmallImage($file,$outFile) {
    $width  = 160;
    $height = 213;
    note('writing small image');
    resizeImage($file,$outFile,$width,$height);
  }
  
  /**
   * Runs a cron job to process images.
   *
   * @param (optional) $user username
   * @param (optional) $pass password
   */
  function run($user=0,$pass=0) {
    global $CONFIG;
    
    if (!$user) $user = config('username');
    if (!$pass) $pass = config('password');
    $email = $user;
    
    // Allow the username to be just that and not an email address But add
    // the server name if none is specified.  This works for me but could
    // slam someone else's buts in the door, so keep that in mind
    if (!preg_match('/.*@.*/',$user)) {
      $server = $_SERVER['SERVER_NAME'];
      $server = preg_replace('/^www\./','',$server);
      $email = $user . '@' . $server;
    }
    
    $mbox = connect($user,$pass);
    note("Using username: $user");
    note("Have mbox: $mbox");
    
    // Options
    $numMsgs = imap_num_msg($mbox);
    $limit = isset($_REQUEST['limit']) ? $_REQUEST['limit'] : 10;
    if ($limit > $numMsgs) {
      $limit = $numMsgs;
    }
    $start = $numMsgs;
  
    note("Starting at $start");
    note("Have $numMsgs messages");
    note("Using limit $limit");
  
    $addressesToAllow = NULL;
    if (config('addresses',FALSE)) {
      $addressesToAllow = preg_split('/,/',config('addresses'));
    }

    // Sanity check
    if ($addressesToAllow = FILL_THIS_IN) {
      $addressesToAllow = NULL;
    }
  
  
    // Maybe add a trailing slash to the output directory
    $outdir = config('relative_path');
    if (!preg_match('/.*\/$/',$outdir)) {
      $outdir .= '/';
    }
  
    // Find the last date
    $lines = file('./last.txt');
    $lastDate = $lines && !isset($_REQUEST['rerun']) ? $lines[0] : 0;
    note("Have last date '$lastDate'");
  
    note("Writing to output directory '$outdir'");
    $count = 0;
    $firstOne = TRUE;
    $firstDate = 0;
    for ($i=0; $count<$limit && $i<$numMsgs; $i++) {
      $msgno = $start-$i;
      $header_info = imap_headerinfo($mbox,$msgno);
    
      if (!$header_info) {
        warn('Skipping header ' . $i);
        continue;
      }
    
      // Maybe only allow certain addresses
      $keep = TRUE;
      if ($addressesToAllow) {
        $keep = FALSE;
        foreach ($addressesToAllow as $addr) {
          if ($from == $addr) {
            $keep = TRUE;
            break;
          }
        }
      }
      if (!$keep) {
        note("Rejecting $from");
        continue;
      }
      
      $this->printLine();
    
      // Get the contents
      $date = $header_info->date;
      if (!$firstDate) $firstDate = $date;
      $subj = $header_info->Subject;
      note("Looking at message $date ... '$subj'");

      // Decide whether to quit or not
      if ($lastDate) {
        if ($date == $lastDate) {
          note("all done");
          break;
        }
      }
      
      $body = imap_fetchbody($mbox,$msgno,"1");
      $img = imap_fetchbody($mbox,$msgno,"2");

      // Get the data from the email
      $description = $body;
      $location    = $subj;
      $who         = getNameFromEmail($header_info->fromaddress);

      // Write the file to 'photo.jpg'
      $sec = datetime();
      $fullFile       = $outdir . $sec . "-full.jpg";
      writeFile($fullFile,imap_base64($img));
      processImageFile($fullFile,$sec,$description,$location);
            
      // Success
      $count++;

      $this->printLine();
      newline();

      // Sleep for a second to get different dates
      sleep(1);
    }

    $names = readNames($outdir);

    note('Have ' . count($names) . ' name(s)');

    // Write the blog
    note('Writing the blog to ' . $this->writeRSS($outdir,$names));

    // Write the base page
    note('Writing the clip page to '. $this->writeNewClipPage($outdir,$names));

    // Write the new file
    note('Writing out new file to ' . $this->writeNewBaseFile($description,$location,$sec,$outdir));
    
    if (count($names) > 0) {
      
      // Record that we're done
      writeFile('last.txt',$firstDate);
      
      note('Copying the latest files');
    
      // copy latest files
      doExec('cp ' . $outdir . $names[0] . '.jpg'        . ' ' . $outdir . 'new.jpg');
      doExec('cp ' . $outdir . $names[0] . '.des'        . ' ' . $outdir . 'new.des');
      doExec('cp ' . $outdir . $names[0] . '.loc'        . ' ' . $outdir . 'new.loc.');
    
    }

  }

  function writeNewClipPage($outdir,$names) {

    global $CONFIG;
    $linkURL = $CONFIG['link_url'];

    $newContents  = '<html>';
    $newContents .= '<head>';
    $newContents .= '<link rel="stylesheet" type="text/css" href="style.css" title="Style" />';
    $newContents .= '</head>';
    $newContents .= '<body>';
    if ($linkURL) $newContents .= '<a href="' . $linkURL . '" border="0">';
    for ($i=0; $i<CLIPS_PER_ROW*CLIP_ROWS; $i++) {
      $name = $names[$i];
      $newContents .= '<img border="0" src="' . $name . '-clip.jpg"></img>';
      if ((($i+1)%CLIP_ROWS) == 0) {
        $newContents .= '<br/>';
      }
    }
    if ($linkURL) $newContents .= '</a>';
    $newContents .= '</p>';
    $newContents .= '</body></html>';
    $outFile = $outdir . 'clip.php';
    writeFile($outFile,$newContents);
    return $outFile;
  }

  function writeNewBaseFile($description,$location,$sec,$outdir,$who=0) {
    $outFile = $outdir . 'new.php';
    note('Writing new base file to ' . $outFile . 'with description ' . $description);
    $newContents  = '<html>';
    $newContents .= '<head>';
    $newContents .= '<link rel="stylesheet" type="text/css" href="style.css" title="Style" />';
    $newContents .= '</head>';
    $newContents .= '<body>';
    $newContents .= '<p>';
    $newContents .= '<img src="new.jpg"><br />';
    $newContents .= '<span class="description">' . $description . '</span><br />';
    $newContents .= '<span class="location">' . $location . '</span><br />';
    $newContents .= '<span class="date">' . format_date($sec) . '</span><br />';
    if ($who && config('show_who')) {
      $newContents .= '<span class="who">by ' . $who . '</span><br />';
    }
    $newContents .= '<a target="_" href="' . config('base_url') . '" border="0">more</a>';
    $newContents .= '</a>';
    $newContents .= '</p>';
    $newContents .= '</body></html>';
    writeFile($outFile,$newContents);
    return $outFile;
  }

  function startRSS() {
    
    global $CONFIG;
    $title = $CONFIG['title'];
    $baseURL = $CONFIG['base_url'];
    $description = $CONFIG['description'];
    $email = $CONFIG['email'];
    
    return '<rss xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:hewsWeb="http://www.hewsweb.org" xmlns:asgard="http://asgard.jrc.it" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gdas="http://gdas.jrc.it" xmlns:geo="http://www.w3.org/2003/01/geo/"><channel><title>' . $title . '</title><link>' . $baseURL . '</link><description>' . $description . '</description><webMaster>' . $email . '</webMaster>';
  }

  function endRSS() {
    return '</channel></rss>';
  }
  
  function writeRSS($base,$names) {
    
    global $CONFIG;
    $baseURL = config('base_url');
    if (!preg_match('/.*\/$/',$baseURL)) {
      $baseURL .= '/';
    }
    
    if (! $dh = opendir($base) ) {
      die("Whoops, couldn't open $base!");
    }
    
    // write out the rss
    $outFile = $base . "index.xml";
    $rssh = fopen($outFile,"w");
    fwrite($rssh,$this->startRSS());
    
    foreach ($names as $name) {
      
      $des = readFileAll($name . '.des');
      $loc = readFileAll($name . '.loc');
      $who = readFileAll($name . '.who');
      $date = format_date($name);
      $img = $name . '.jpg';
      
      $rssDate = $this->rssDate($name);
      
      $xml = "<item>"
        . "<title>" . $des . "</title>"
        . "<description><img src='" . $baseURL . "$img' /> " . $des 
        . " at " . $loc . " on " . $date;
      if (config('show_who') && $who) {
        $xml .= ' by ' . $who;
      }
      $xml .=  "</description>"
        . "<link>" . config('base_url')  . "</link>"
        . "<pubDate>" . $rssDate  . "</pubDate>"
        . "</item>";
      fwrite($rssh,$xml);  
    }
    
    fwrite($rssh,$this->endRSS());
    fclose($rssh);

    return $outFile;
  }
  
  // <pubDate>Wed, 02 Oct 2002 08:00:00 EST</pubDate>
  function rssDate($dt) {
    
    //20060226062615
    $year      = substr($dt, 0, 4);
    $month     = substr($dt, 4, 2);
    $day       = substr($dt, 6, 2);
    $hour      = substr($dt, 8, 2);
    $minutes   = substr($dt,10, 2);
    $seconds   = substr($dt,12, 2);
    
    $hour = (int)$hour + 3; // don't know why?
    
    $monthString = number2month($month);
    
    return "Wed, $day $monthString $year $hour:$minutes:$seconds EST";
  }

  function printLine() {
    say('------------------------------------------------------------------------------------------','#770077');
  }

}

?>